﻿// Inner Fire 游戏引擎库
// 普通Windows类
//
// Copyright (c) 2024 by 尔西大帝. All rights reserved.
//
// 合并用于Windows的工具
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2024-11-29

#pragma once

#include "../framework.h"
#include "kits.h"
#include <dx/graphics/dx_graphics.h>
#include <game/manager/game_manager.h>
#include <klua.h>
#include "SplashScreen.h"

using namespace ifire;

class WindowApp {
public:
  WindowApp();
  WindowApp(const WindowApp&) = delete;
  WindowApp& operator=(const WindowApp&) = delete;
  ~WindowApp();

  bool Init(HINSTANCE hInstance, int nCmdShow);
  void Load();

  void Update();
  bool IsRunning() { return is_running_; }
  bool IsLoaded() { return is_loaded_; }
  // 处理事件
  void RollEvents();

  HWND GetHandle() { return hwnd_; }
  UINT GetClientWidth() { return client_width_; }
  UINT GetClientHeight() { return client_height_; }
  int OnResize(WPARAM wParam, LPARAM lParam);
  // 更新Splash窗口
  void DrawSplash(float progress);

  static WindowApp* GetApp();
  static ikit::XmlReader GetConfig();

  LRESULT CALLBACK WndProc(
      HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
  INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

private:
  ATOM MyRegisterClass(HINSTANCE hInstance);
  int OnSizeMove(bool is_enter);
  void OnMouseDown(WPARAM btn_state, int button_id, int x, int y);
  void OnMouseUp(WPARAM btn_state, int button_id, int x, int y);
  void OnMouseMove(WPARAM btn_state, int x, int y);
  void OnKeyDown(WPARAM key_state);
  void OnKeyUp(WPARAM key_state);
  void OnChar(WPARAM char_state);
  LRESULT OnMouseWheel(WPARAM wParam, LPARAM lParam);
  LRESULT OnCommand(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

private:
  // 信息
  MSG msg_;
  // 快捷键句柄
  HACCEL accel_table_;
  // 应用程序句柄
  HINSTANCE hInstance_;
  // 窗口句柄
  HWND hwnd_;
  // 程序是否在运行。当窗口关闭时设置为false
  bool is_running_;
  // 标记是否载入完成
  bool is_loaded_;

  // 渲染视口部分的宽高
  UINT client_width_, client_height_;
  // 整个窗口的宽高
  LONG width_, height_;
  // DirectX主渲染器
  dx::DxGraphics* dx_ = nullptr;
  // 游戏主控制器
  game::GameManager* gm_ = nullptr;
  // 游戏的启动界面
  SplashScreen splash;
  // 当前载入的项目
  int current_load_stage_ = 0;

  // 是否锁定帧数
  bool is_lock_frame = false;

  // 用于控制窗口大小。当窗口最小化时，程序需要停止。也无法渲染。
  bool app_paused_;
  bool minimized_;
  bool maximized_;
  bool is_resizing_; // 标记是否还正在重设置窗口。
};